﻿using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using OpenXmlPowerTools;

namespace Songhay.OpenXml.Transformations
{
    using Songhay.OpenXml.Models;

    /// <summary>
    /// Transforms the Open XML WordML <c>p</c> element
    /// for headings.
    /// </summary>
    /// <remarks>
    // Transform every paragraph with a style that has paragraph properties
    // that has an outline level into the same level of heading.  This takes
    // care of transforming headings of every level.
    /// </remarks>
    [Export(typeof(IWordProcessingDocumentTransformation))]
    public class HeadingsTransformation : IWordProcessingDocumentTransformation
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="HeadingsTransformation"/> class.
        /// </summary>
        public HeadingsTransformation()
        {
            this.ExecutionOrdinal = 2;
        }

        #region IWordProcessingDocumentTransform Members

        public byte ExecutionOrdinal { get; set; }

        /// <summary>
        /// Determines whether this instance can transform the specified word doc.
        /// </summary>
        /// <param name="wordDoc">The Word document.</param>
        /// <param name="settings">The settings.</param>
        /// <param name="node">The node.</param>
        /// <returns>
        /// 	<c>true</c> if this instance can transform the specified word doc; otherwise, <c>false</c>.
        /// </returns>
        public bool CanTransform(WordprocessingDocument wordDoc,
            SonghayHtmlConverterSettings settings, XNode node)
        {
            if(!this.HasElementName(node, SonghayW.p)) return false;

            var element = node as XElement;

            styleId = (string)element
                .Elements(SonghayW.pPr).Elements(SonghayW.pStyle)
                .Attributes(SonghayW.val).FirstOrDefault();

            XElement style = wordDoc
                .MainDocumentPart.StyleDefinitionsPart
                .GetXDocument().Root.Elements(SonghayW.style)
                .Where(s => (string)s.Attribute(SonghayW.styleId) == styleId)
                .FirstOrDefault();

            if(style != null)
            {
                outlineLevel = (int?)style
                    .Elements(SonghayW.pPr).Elements(SonghayW.outlineLvl)
                    .Attributes(SonghayW.val).FirstOrDefault();

                return (outlineLevel != null);
            }

            return false;

        }

        /// <summary>
        /// Transforms the specified Word document.
        /// </summary>
        /// <param name="wordDoc">The Word document.</param>
        /// <param name="settings">The settings.</param>
        /// <param name="node">The node.</param>
        /// <param name="imageHandler">The image handler.</param>
        /// <returns></returns>
        public object Transform(WordprocessingDocument wordDoc,
            SonghayHtmlConverterSettings settings, XNode node,
            Func<ImageInfo, XElement> imageHandler)
        {
            var element = node as XElement;

            var y = new XElement(SonghayXhtml.xhtml + string.Format("h{0}", outlineLevel + 1),
                settings.CssClassPrefix != null ?
                    new XAttribute(SonghayXhtml.@class,
                        settings.CssClassPrefix + styleId) : null,
                OpenXmlUtility.TranslateEntities(ListItemRetriever.RetrieveListItem(wordDoc,
                    element, null), settings),
                element.Elements().Select(e => OpenXmlUtility.TransformPackageNode(wordDoc,
                    settings, e, imageHandler)));

            return OpenXmlUtility.RenderEmptyElement(y);
        }

        #endregion

        int? outlineLevel;
        string styleId;
    }
}
